package com.seanzx.resolver.impl;

import com.seanzx.common.Result;
import com.seanzx.constant.SymbolTable;
import com.seanzx.lexical.Token;
import com.seanzx.lexical.TokenType;
import com.seanzx.resolver.IResolver;
import com.seanzx.dp.ProcessorController;
import com.seanzx.dp.common.ColumnType;
import com.seanzx.dp.entity.Column;
import com.seanzx.dp.entity.Table;

import java.util.ArrayList;
import java.util.List;

public class CreateTableResolver implements IResolver<Table> {
    private final ProcessorController processorController = ProcessorController.get();

    @Override
    public boolean matches(List<Token> tokens) {
        return tokens.size() > 3 &&
                tokens.get(0).getValue().equals(SymbolTable.CREATE) &&
                tokens.get(1).getValue().equals("TABLE");
    }

    @Override
    public Table translate(List<Token> tokens) {
        String databaseName, tableName;
        int startIndex;
        if (tokens.get(3).getValue().equals(".")) {
            databaseName = tokens.get(2).getValue();
            tableName = tokens.get(4).getValue();
            startIndex = 5;
        } else {
            databaseName = null;
            tableName = tokens.get(2).getValue();
            startIndex = 3;
        }
        List<Column> columns = new ArrayList<>();
        Column column = null;
        for (int i = startIndex; i < tokens.size(); i++) {
            Token token = tokens.get(i);
            if (column == null && token.getType().equals(TokenType.VALUE)) {
                column = Column.builder().tableSchema(databaseName).tableName(tableName).name(token.getValue()).build();
            }
            assert column != null;

            boolean isType = false;
            for (ColumnType value : ColumnType.values()) {
                if (value.toString().equals(token.getValue())) {
                    column.setType(value);
                    if ("(".equals(tokens.get(i + 1).getValue())) {
                        i++;
                        column.setLength(Integer.parseInt(tokens.get(++i).getValue()));
                        i++;
                    }
                    isType = true;
                    break;
                }
            }
            if (isType) {
                continue;
            }
            if ("COMMENT".equals(token.getValue())) {
                column.setComment(tokens.get(i++).getValue());
                continue;
            }
            if (",".equals(token.getValue())) {
                column.setIndex(columns.size());
                columns.add(column);
                column = Column.builder().tableSchema(databaseName).tableName(tableName).name(tokens.get(++i).getValue()).build();
            }
            if (")".equals(token.getValue())) {
                column.setIndex(columns.size());
                columns.add(column);
                break;
            }
        }
        return Table.builder().tableSchema(databaseName).name(tableName).columns(columns).build();
    }

    @Override
    public boolean validate(Object parameter) {
        return true;
    }

    @Override
    public Result access(Object parameter) {
        Table table = (Table) parameter;
        if (table.getTableSchema() != null) {
            return processorController.createTable(table.getTableSchema(), table);
        }
        return processorController.createTable(table);
    }

}
